#ifndef FRUSTUM_H
#define FRUSTUM_H

#include "Framework/Prerequisites.h"
#include "Geometry/Plane.h"

namespace tyro
{
	namespace Geometry
	{

		enum FrustumPlane
		{
			FRUSTUM_NEAR_PLANE   = 0,
			FRUSTUM_FAR_PLANE    = 1,
			FRUSTUM_LEFT_PLANE   = 2,
			FRUSTUM_RIGHT_PLANE  = 3,
			FRUSTUM_TOP_PLANE    = 4,
			FRUSTUM_BOTTOM_PLANE = 5
		};

		class Frustum
		{
		public:

			
			void Initialise(Camera::Camera* camera);

			const Math::Quaternionf& GetOrientation(void) const;
			tyro::FLOAT_32 GetLeftExtern() const;
			tyro::FLOAT_32 GetRightExtern() const;
			tyro::FLOAT_32 GetBottomExtern() const ;
			tyro::FLOAT_32 GetTopExtern() const ;
			tyro::FLOAT_32 GetNearClipDistance() const;
			tyro::FLOAT_32 GetFarClipDistance() const ;
			tyro::FLOAT_32 GetAspectRatio() const;
			Math::Matrix4f GetProjectionMatrix() const ;
			const Math::Matrix4f& GetProjectionMatrixRS(void) const;
			Math::Matrix4f GetViewMatrix() const;
			const Math::Vector3f& GetTranslation( void ) const;
			void SetParentCamera(Camera::Camera* camera);
			void SetFOVy(tyro::FLOAT_32 val);
			void SetFocalLength(tyro::FLOAT_32 val);
			void SetLeftExtern(tyro::FLOAT_32 val);
			void SetRightExtern(tyro::FLOAT_32 val);
			void SetBottomExtern(tyro::FLOAT_32 val) ;
			void SetTopExtern(tyro::FLOAT_32 val);
			void SetNearClipDistance(tyro::FLOAT_32 val);
			void SetAspectRatio(tyro::FLOAT_32 val);
			void SetFarClipDistance(tyro::FLOAT_32 val) ;
			void SetProjectionMatrix(Math::Matrix4f val) ;
			void SetViewMatrix(Math::Matrix4f val);
			void SetProjectionType(ProjectionType pt);
			void SetFrustumOffset( const Math::Vector2f& offset );
			void UpdateFrustum() const;
			void UpdateFrustumImpl() const;
			void UpdateView() const;
			void UpdateViewImpl() const;
			void UpdateFrustumPlanes() const;
			void UpdateFrustumPlanesImpl(void) const;
			void CalcProjection( FLOAT_32& left, FLOAT_32& right, FLOAT_32& bottom, FLOAT_32& top ) const;
		protected:

			mutable FLOAT_32  	left;
			mutable FLOAT_32  	right;
			mutable FLOAT_32  	bottom;
			mutable FLOAT_32  	top;
			FLOAT_32  	nearVal;
			FLOAT_32  	farVal;
			FLOAT_32	aspectRatio;
			FLOAT_32	focalLength;
			FLOAT_32	FOVy;
			mutable Math::Matrix4f projectionMatrix;
			mutable Math::Matrix4f projectionMatrixRS;
			mutable Math::Matrix4f viewMatrix;
			mutable Plane frustumPlanes[6];
			Camera::Camera*		parentCamera;
			ProjectionType projectionType;
			Math::Vector2f frustumOffset;
			bool updated;
		};

	}
}

#endif